from django.core.management.base import BaseCommand
from optparse import make_option
from django.utils.encoding import smart_unicode
import sys, pprint

class Command(BaseCommand):
    option_list = BaseCommand.option_list + (
        make_option('--feeds', action='store_true', dest='syncfeed', default=False,
            help='Synchronizes your FriendFeed using information in your settings file.'),
        make_option('--likes', action='store_true', dest='synclikes', default=False,
            help='Synchronizes your FriendFeed "likes" using information in your settings file.'),
        make_option('--all', action='store_true', dest='all', default=False,
            help='Goes back in time and tries to fill in all your old entries.'),
        make_option('--service', action='store', dest='service', default='',
            help='Limits the retrieval to a particular service'),
    )
    help = 'Runs a script that contacts FriendFeed, downloads your activity and synchronizes it to the local database'
    args = ''

    requires_model_validation = False

    def handle(self, *test_labels, **options):
        from django.conf import settings
        from django.db.models import get_app, get_apps
        from friendfeed import FriendFeed
        synclikes = options.get('synclikes', True)
        syncfeed = options.get('syncfeed', True)
        get_all = options.get('all', False)
        service = options.get('service', '')
        if getattr(settings, 'FRIENDFEED_NICKNAME', False):
            friendfeed_nickname = settings.FRIENDFEED_NICKNAME
        else:
            sys.exit('Please set FRIENDFEED_NICKNAME in your settings.py file')
        if syncfeed or synclikes:
            f = FriendFeed()
        if syncfeed:
            print "Grabbing entries:"
            get_entries(nickname=friendfeed_nickname, get_all=get_all, service=service, endpoint=f.fetch_user_feed)
        if synclikes:
            print "Grabbing likes:"
            get_entries(nickname=friendfeed_nickname, get_all=get_all, service=service, endpoint=f.fetch_user_likes_feed)

def get_entries(nickname='', get_all=False, service='', endpoint=None):
    if endpoint and nickname:
        keep_going = True
        start = 0
        per_page = 30
        last = ''
        num_created = 0
        while keep_going:
            if service != '':
                print "%s:" % (service,)
            print "  Pulling %s entries from %s to %s" % (nickname, start, start+per_page)
            feed = endpoint(nickname, start=start, num=per_page, service=service)
            for e in feed['entries']:
                new_entry, created = entry_to_models(e)
                if created:
                    num_created += 1
            start += per_page
            if len(feed['entries']):
                if feed['entries'][0]['id'] == last or not get_all:
                    keep_going = False
                last = feed['entries'][0]['id']
            else:
                keep_going = False
        print "      Created %s new entries" % (num_created,)
    else:
        return False
        
def entry_to_models(entry):
    from friendly.models import Entry, Service, Media, Like, Comment, MediaContent, MediaThumbnail
    import datetime
    s = entry.get('service')
    service, created = Service.objects.get_or_create(
        ff_id   = s.get('id'),
        defaults = {
            'ff_id'     : s.get('id'),
            'name'      : s.get('name'),
            'iconURL'   : s.get('iconUrl'),
            'profileURL': s.get('profileUrl'),
        }
    )
    
    u = entry.get('user')
    user = get_user(u)

    if len(entry.get('link')) > 100:
        return None,None
    
    e, entry_created = Entry.objects.get_or_create(
        ff_id       = entry.get('id', ''),
        defaults    = {
            'ff_id'     : entry.get('id'),
            'title'     : smart_unicode(entry.get('title')),
            'link'      : entry.get('link'),
            'published' : entry.get('published', datetime.datetime.now()),
            'updated'   : entry.get('updated', datetime.datetime.now()),
            'hidden'    : entry.get('hidden', False),
            'anonymous' : entry.get('anonymous', False),
            'via'       : entry.get('via', {'name': ''})['name'],
            'service'   : service,
            'user'      : user,
        }
    )
    
    if entry_created:
        print "    *** Added %s (%s)" % (smart_unicode(e.title), e.service.name)
    
    # If I'm correct, media is static once the entry is created
    medias = entry.get('media', [])
    if entry_created and medias:
        for m in medias:
            media = Media(
                title   = m.get('title', ''),
                player  = m.get('player', ''),
                entry   = e,
            )
            media.save()
            
            thumbnails = m.get('thumbnails', [])
            contents = m.get('content', [])
            
            if thumbnails:
                for t in thumbnails:
                    thumbnail = MediaThumbnail(
                        url     = t.get('url'),
                        width   = t.get('width'),
                        height  = t.get('height'),
                        media   = media,
                    )
                    thumbnail.save()
            if contents:
                for c in contents:
                    content = MediaContent(
                        url     = c.get('url'),
                        type    = c.get('type'),
                        width   = c.get('width'),
                        height  = c.get('height'),
                        media   = media,
                    )
                    content.save()

    # Likes and Comments can be added at anytime
    comments = entry.get('comments', [])
    likes = entry.get('likes', [])
    if likes:
        for l in likes:
            u = l.get('user')
            user = get_user(u)
                
            like, created = Like.objects.get_or_create(
                entry   = e.id,
                user    = user,
                date    = l.get('date'),
                defaults = {
                    'entry' : e,
                    'user'  : user,
                    'date'  : l.get('date'),
                }
            )
    
    if comments:
        for c in comments:
            u = c.get('user')
            user = get_user(u)
            comment, created = Comment.objects.get_or_create(
                ff_id       = c.get('id'),
                defaults    = {
                    'ff_id' : c.get('id'),
                    'date'  : c.get('date'),
                    'user'  : user,
                    'body'  : smart_unicode(c.get('body')),
                    'entry' : e,
                }
            )
    
    return entry, entry_created
    
def get_user(u):
    from friendly.models import User
    user, created = User.objects.get_or_create(
        ff_id       = u.get('id'),
        defaults    = {
            'ff_id'     : u.get('id'),
            'name'      : smart_unicode(u.get('name')),
            'nickname'  : smart_unicode(u.get('nickname')),
            'profileURL': u.get('profileUrl'),
        }
    )
    return user